/**************************************************************************//**
 * @item     CosyOS-II Kernel
 * @file     sv_int_pend_fifo.c
 * @brief    中断挂起服务_FIFO - 执行函数
 * @details  仅在 PendSV 中由系统调用并执行。
 * @author   迟凯峰
 * @version  V3.2.0
 * @date     2024.12.13
 ******************************************************************************/

#include "os_link.h"
#if MCUCFG_PENDSVFIFO_DEPTH > 0

/**
 @addtogroup CosyOS_内核服务
 @{
 *//**
 \defgroup   中断挂起服务_FIFO
 \brief      在中断中调用的服务，不在本地执行，而是把服务的内容写入局部的结构体中，
             再把结构体指针入 PendSV_FIFO，再触发 PendSV，而后在 PendSV 中执行。
 @{
 */

/**
 \page       手动裁剪说明：

         \li 本页中的各个执行函数，任何编译器都无法自动移除未使用，原因是<br>
             它们是通过函数指针间接调用的。

         \li 如果您希望做到极致的裁剪，可逐一查看这些函数，确定不使用的，<br>
             可通过 手动开关 进行手动移除。
 */

/**
 \brief      清除就绪延时
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iClearDelay。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/
static void _clear_delay_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	if(sv == OS_NULL) return; /* 该句无实际用途，只为屏蔽可能的编译器警告 */
	if(s_sign_schedule_forbid){
		s_task_current->timer = 0;
	}
}
#else
#define _clear_delay_ OS_NULL
#endif

/**
 \brief      切换任务
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iSwitchTask(task)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/
static void _switch_task_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp htask = ((sp_task_tsp)sv)->htask;
	if(htask == OS_NULL) return;
	if(htask->status < OS_STATUS_STOPPED){
		s_switch_taskpri(htask);
	}
}
#else
#define _switch_task_ OS_NULL
#endif

/**
 \brief      恢复任务
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iResumeTask(task)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/
static void _resume_task_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp htask = ((sp_task_tsp)sv)->htask;
	if(htask == OS_NULL) return;
	if(htask->status & OS_STATUS_SUSPENDED){
		htask->status &= (~OS_STATUS_SUSPENDED & 0xFF);
		s_switch_ready(htask);
	}
}
#else
#define _resume_task_ OS_NULL
#endif

/**
 \brief      挂起任务
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iSuspendTask(task)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/
static void _suspend_task_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp htask = ((sp_task_tsp)sv)->htask;
	if(htask == OS_NULL) return;
	if(htask->status < OS_STATUS_SUSPENDED){
		htask->status |= OS_STATUS_SUSPENDED;
		if(htask == s_task_current){
			s_sign_schedule = true;
		}
	}
}
#else
#define _suspend_task_ OS_NULL
#endif

/**
 \brief      删除任务
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iDeleteTask(task)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/
static void _delete_task_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp htask = ((sp_task_tsp)sv)->htask;
	if(htask == OS_NULL) return;
	if(htask->status < OS_STATUS_DELETED){
		htask->status = OS_STATUS_DELETED;
		if(htask == s_task_current){
			s_sign_schedule = true;
		}
	}
}
#else
#define _delete_task_ OS_NULL
#endif

/**
 \brief      设置任务优先级
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iSetTaskPri(task, pri)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/
static void _set_taskpri_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp htask = ((sp_taskpri_tsp)sv)->htask;
	if(htask == OS_NULL) return;
	if(htask->status < OS_STATUS_STOPPED){
		s_u8_t pri = ((sp_taskpri_tsp)sv)->pri;
		if(htask->pri != pri){
			htask->pri = pri;
			s_set_taskpri(htask);
			s_sign_schedule = true;
		}
	}
}
#else
#define _set_taskpri_ OS_NULL
#endif

/**
 \brief      设置阻塞（时间）
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iSetBlock_tc(task, tc)、iSetBlock_ms(task, ms)、
                       iSetBlock_s(task, s)、iSetBlock_m(task, m)、iSetBlock_h(task, h)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/
static void _set_block_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp htask = ((sp_blocktime_tsp)sv)->htask;
	if(htask == OS_NULL) return;
	if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){
		if(!((sp_blocktime_tsp)sv)->tick){
			htask->status = OS_STATUS_READY;
			s_switch_taskpri(htask);
		}
		htask->timer = ((sp_blocktime_tsp)sv)->tick;
	}
}
#else
#define _set_block_ OS_NULL
#endif

/**
 \brief      清除阻塞（状态）
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iClearBlock(task)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/
static void _clear_block_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_tasknode_tsp htask = ((sp_task_tsp)sv)->htask;
	if(htask == OS_NULL) return;
	if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){
		htask->status = OS_STATUS_READY;
		htask->timer = 0;
		s_switch_taskpri(htask);
	}
}
#else
#define _clear_block_ OS_NULL
#endif

/**
 \brief      定时中断
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iTimInt_tc(tmid, tc)、iTimInt_ms(tmid, ms)、iTimInt_s(tmid, s)、
                       iTimInt_m(tmid, m)、iTimInt_h(tmid, h)、iTimInt_Cancel(tmid)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/ \
 && OS_TIMINTTOTAL
static void _timint_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	  s_timint_handle[((sp_timint_tsp)sv)->tmid]->timer
	= s_timint_handle[((sp_timint_tsp)sv)->tmid]->reload
	= ((sp_timint_tsp)sv)->tick;
}
#else
#define _timint_ OS_NULL
#endif

/**
 \brief      定时查询
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iTimQry_tc(tmid, tc)、iTimQry_ms(tmid, ms)、iTimQry_s(tmid, s)、
                       iTimQry_m(tmid, m)、iTimQry_h(tmid, h)、iTimQry_Cancel(tmid)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/ \
 && OS_TIMQRYTOTAL
static void _timqry_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	  s_timqry_handle[((sp_timqry_tsp)sv)->tmid]->timer
	= s_timqry_handle[((sp_timqry_tsp)sv)->tmid]->reload
	= ((sp_timqry_tsp)sv)->tick;
}
#else
#define _timqry_ OS_NULL
#endif

/**
 \brief      上锁or给予二值信号量
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iLockBin(bin)、iGiveBin(bin)、iBackBin(bin)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/ \
 && SYSCFG_BINARY == __ENABLED__
static void _binary_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_binary_tsp hbin = ((sp_binary_tsp)sv)->hbin;
	hbin->binary = ((sp_binary_tsp)sv)->value;
	if(!hbin->binary) return;
	s_switch_notnull(hbin->htask);
}
#else
#define _binary_ OS_NULL
#endif

/**
 \brief      给予计数信号量
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iGiveSem(sem)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/ \
 && SYSCFG_SEMAPHORE == __ENABLED__
static void _give_sem_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_semaph_tsp hsem = ((sp_semaph_tsp)sv)->hsem;
	if(hsem->counter < hsem->maximum){
		hsem->counter++;
	}
	s_switch_notnull(hsem->htask);
}
#else
#define _give_sem_ OS_NULL
#endif

/**
 \brief      发送飞信
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iSendFetion(tbox, tion)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/ \
 && SYSCFG_FETION == __ENABLED__
static void _send_fetion_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_tionbox_tsp htbox = ((sp_tionbox_tsp)sv)->htbox;
	htbox->fetion = ((sp_tionbox_tsp)sv)->fetion;
	s_switch_notnull(htbox->htask);
}
#else
#define _send_fetion_ OS_NULL
#endif

/**
 \brief      发送邮件
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iSendMail(mbox, mail)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/ \
 && SYSCFG_MAILBOX == __ENABLED__
static void _send_mail_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_mailbox_tsp hmbox = ((sp_mailbox_tsp)sv)->hmbox;
	hmbox->flag = false;
	hmbox->mail = ((sp_mailbox_tsp)sv)->mail;
	hmbox->flag = true;
	s_switch_notnull(hmbox->htask);
}
#else
#define _send_mail_ OS_NULL
#endif

/**
 \brief      发送消息
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iSendMsg(que, msg)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/ \
 && SYSCFG_MSGQUEUE == __ENABLED__
static void _send_msg_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	s_queue_tsp hque = ((sp_msg_tsp)sv)->hque;
	hque->mutex = false;
	
	if(hque->counter == hque->len){
		#if SYSCFG_DEBUGGING == __ENABLED__
		s_alarm.overflow_msgqueue = true;
		#endif
		hque->mutex = true;
		return;
	}
	if(hque->type == __DYNAMIC__){
		s_msgnode_tsp hmsg = OS_NULL;
		hmsg = (s_msgnode_tsp)s_malloc(sizeof(s_msgnode_ts));
		if(hmsg == OS_NULL){
			#if SYSCFG_DEBUGGING == __ENABLED__
			s_fault.mallocfailed_msgnode = true;
			#endif
			hque->mutex = true;
			return;
		}
		sSendMsg_Dynamic(((sp_msg_tsp)sv)->msg);
	}
	else
		sSendMsg_Static(((sp_msg_tsp)sv)->msg);
	
	s_switch_notnull(hque->htask);
	hque->mutex = true;
}
#else
#define _send_msg_ OS_NULL
#endif

/**
 \brief      写标志组
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iClearFlagGroup(group)、
                       iSetFlagBit(group, bit)、iSetFlagBits(group, nbit) ...)、
                       iClearFlagBit(group, bit)、iClearFlagBits(group, nbit) ...)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/ \
 && SYSCFG_FLAGGROUP == __ENABLED__
static void _group_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	switch(((sp_group_tsp)sv)->size){
	case +1: *(s_u8_t  *)((sp_group_tsp)sv)->hgrp |= ((sp_group_tsp)sv)->value; break;
	case +2: *(s_u16_t *)((sp_group_tsp)sv)->hgrp |= ((sp_group_tsp)sv)->value; break;
	case +4: *(s_u32_t *)((sp_group_tsp)sv)->hgrp |= ((sp_group_tsp)sv)->value; break;
	case -1: *(s_u8_t  *)((sp_group_tsp)sv)->hgrp &=~((sp_group_tsp)sv)->value; break;
	case -2: *(s_u16_t *)((sp_group_tsp)sv)->hgrp &=~((sp_group_tsp)sv)->value; break;
	case -4: *(s_u32_t *)((sp_group_tsp)sv)->hgrp &=~((sp_group_tsp)sv)->value; break;
	}
}
#else
#define _group_ OS_NULL
#endif

/**
 \brief      全局变量写访问
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iWriteGVar(gv, lv)、iWriteGAry(gp, lp, size)、iWriteGStr(gs, ls)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/
static void _gvar_write_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	((sp_gvar_tsp)sv)->size
	? s_memcpy(((sp_gvar_tsp)sv)->gp, ((sp_gvar_tsp)sv)->lp, ((sp_gvar_tsp)sv)->size)
	: s_strcpy((char *)((sp_gvar_tsp)sv)->gp, (char *)((sp_gvar_tsp)sv)->lp);
}
#else
#define _gvar_write_ OS_NULL
#endif

/**
 \brief      挂起服务调用
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iPendSVC(fp)。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/
static void _pendsvc_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	(*((sp_pendsvc_tsp)sv)->fp)();
}
#else
#define _pendsvc_ OS_NULL
#endif

/**
 \brief      发送信号
 \param[in]  sv        服务的结构体指针
 \return     无
 \note       关联服务：iSendSign(sign)；
                       iSetTime(t) [系统配置中，当 中断中获取RTC 选项为启用，
                       即 SYSCFG_GETRTC_INT == 1 时，调用该服务]。
 */
#if 1 /* 手动开关 *//* 如果用户不会调用关联服务，可手动移除该函数（1 改为 0）*/
static void _send_sign_(void _STATIC_MEM_ *sv) MCUCFG_C51USING
{
	*((sp_sign_tsp)sv)->sign = true;
}
#else
#define _send_sign_ OS_NULL
#endif

/**
 \brief      中断挂起服务_FIFO - 执行总函数（函数指针数组）
 \param[in]  [SVID]    服务ID
 \param[in]  sv        服务的结构体指针
 \return     无
 */
void (_CODE_MEM_ * const _CONST_MEM_ sPendSV_FIFOHandler[OS_SVID_END])(void _STATIC_MEM_ *sv) =
{
	_clear_delay_,
	_switch_task_,
	_resume_task_,
	_suspend_task_,
	_delete_task_,
	_set_taskpri_,
	_set_block_,
	_clear_block_,
	_timint_,
	_timqry_,
	_binary_,
	_give_sem_,
	_send_fetion_,
	_send_mail_,
	_send_msg_,
	_group_,
	_gvar_write_,
	_pendsvc_,
	_send_sign_
};

/** @} */
/** @} */
#endif
